#include "ContactsServer.h"
#include "../common/ContactException.h"
#include "../common/Utils.h"

// ContactsServer::

void ContactsServer::add(add_contact_req::AddContactsRequest &request,
                         add_contact_resp::AddContactResponse *response) const
{
    // 打印日志
    printAddContactRequest(request);
    // 读取已经存在的contacts
    contacts::Contacts contacts;
    contactsMapper.selectContacts(&contacts);
    // 转化为存入文件的消息对象
    google::protobuf::Map<std::string, contacts::PeopleInfo> *map_contacts = contacts.mutable_contacts();
    contacts::PeopleInfo people;
    buildPeopleInfo(&people, request);
    map_contacts->insert({people.uid(), people});
    // 向磁盘中写入新的contacts(构造resp)
    contactsMapper.insertContacts(contacts);
    response->set_uid(people.uid());
    response->mutable_base_resp()->set_success(true);
    // 打印日志
    std::cout << "---->(ContactsServer::add) Succrss to write contacts. " << std::endl;
    //
    //
}

void ContactsServer::del(del_contact_req::DelContactRequest &request,
                         del_contact_resp::DelContactResponse *response) const
{
    // 打印日志
    std::cout << "---->(ContactsServer::del) DelContactRequest uid: " << request.uid() << std::endl;
    // 读取已经存在的contacts
    contacts::Contacts contacts;
    contactsMapper.selectContacts(&contacts);
    // 根据uid进行操作
    // 先判断要删除的uid是否存在
    if (contacts.contacts().find(request.uid()) == contacts.contacts().end())
    {
        std::cout << "---->(ContactsServer::del) not find uid::" << request.uid() << std::endl;
        response->set_uid(request.uid());
        response->mutable_base_resp()->set_success(false);
        response->mutable_base_resp()->set_error_desc("not find uid");
        return;
    }
    contacts.mutable_contacts()->erase(request.uid());
    // 向磁盘中写入新的contacts(构造resp)
    contactsMapper.insertContacts(contacts);
    response->set_uid(request.uid());
    response->mutable_base_resp()->set_success(true);
    // 打印日志
    std::cout << "---->(ContactsServer::del) success to del contact,uid:" << request.uid() << std::endl;
}

void ContactsServer::find_one(find_one_contact_req::FindOneContactRequest &request,
                              find_one_contact_resp::FindOneContactResponse *response) const
{
    // 打印日志
    std::cout << "---->(ContactsServer::find_one) FindOneContactRequest uid:" << request.uid() << std::endl;
    // 读取已经存在的contacts
    contacts::Contacts contacts;
    contactsMapper.selectContacts(&contacts);
    // 查看find联系人是否存在
    // 转化resp消息对象
    const google::protobuf::Map<std::string, contacts::PeopleInfo> &map_contacts = contacts.contacts();
    auto iter = map_contacts.find(request.uid());
    if (map_contacts.end() == iter)
    {
        std::cout << "---->(ContactsServer::find_one) not find uid:" << request.uid() << std::endl;
        response->mutable_base_resp()->set_success(false);
        response->mutable_base_resp()->set_error_desc("uid not find");
        return;
    }
    // 构造response返回
    buildFindOneContactResponse(iter->second, response);
    // 打印日志
    std::cout << "---->(ContactsServer::find_one) find uid:" << request.uid() << std::endl;
}

void ContactsServer::find_all(find_all_contacts_resp::FindAllContactsResponse *response) const
{
    // 打印日志
    std::cout << "---->(ContactsServer::find_all) " << std::endl;
    // 读取已经存在的contacts
    contacts::Contacts contacts;
    contactsMapper.selectContacts(&contacts);
    // 转化resp消息对象
    buildFindAllContactsResponse(contacts, response);
    // 打印日志
    std::cout << "---->(ContactsServer::find_all) success" << std::endl;
}

// 打印已经存在联系人信息日志
void ContactsServer::printAddContactRequest(add_contact_req::AddContactsRequest &request) const
{
    std::cout << "---->(ContactsServer::add) AddContactsRequest:";
    std::cout << "姓名:" << request.name() << std::endl;
    std::cout << "年龄" << request.age() << std::endl;
    for (auto &phone : request.phone())
    {
        int j = 1;
        std::cout << "电话" << j << " : " << phone.number();
        std::cout << "(" << phone.PhoneType_Name(phone.type()) << ")" << std::endl;
    }
    if (request.remake_size())
    {
        std::cout << "备注信息" << std::endl;
    }

    for (auto it = request.remake().cbegin(); it != request.remake().cend(); ++it)
    {
        std::cout << " " << it->first << " : " << it->second << std::endl;
    }
}

// 该函数对应的是void ContactsServer::add()函数中，添加联系人详细信息的具体操作
void ContactsServer::buildPeopleInfo(contacts::PeopleInfo *people,
                                     add_contact_req::AddContactsRequest &request) const
{
    std::string uid = Utils::generate_hex(10);
    people->set_uid(uid);
    people->set_name(request.name());
    people->set_age(request.age());
    for (auto &phone : request.phone())
    {
        contacts::PeopleInfo_Phone *peo_phone = people->add_phone();
        peo_phone->set_number(phone.number());
        switch (phone.type())
        {
        case add_contact_req::AddContactsRequest_Phone_PhoneType::AddContactsRequest_Phone_PhoneType_MP:
            peo_phone->set_type(contacts::PeopleInfo_Phone_PhoneType::PeopleInfo_Phone_PhoneType_MP);
            break;
        case add_contact_req::AddContactsRequest_Phone_PhoneType::AddContactsRequest_Phone_PhoneType_TEL:
            peo_phone->set_type(contacts::PeopleInfo_Phone_PhoneType::PeopleInfo_Phone_PhoneType_TEL);
            break;
        default:
            std::cout << "请正确选择输入号码的类型" << std::endl;
            break;
        }
    }
    Utils::map_copy(people->mutable_remark(), request.remake());
}

// 针对find_one函数中对于查找到联系人之后该联系人的详细信息的具体输出操作
void ContactsServer::buildFindOneContactResponse(const contacts::PeopleInfo &people,
                                                 find_one_contact_resp::FindOneContactResponse *response) const
{
    if (nullptr == response)
        return;
    response->mutable_base_resp()->set_success(true);
    response->set_uid(people.uid());
    response->set_name(people.name());
    response->set_age(people.age());
    for (auto &phone : people.phone())
    {
        find_one_contact_resp::FindOneContactResponse_Phone *resp_phone = response->add_phone();
        resp_phone->set_number(phone.number());
        switch (phone.type())
        {
        case contacts::PeopleInfo_Phone_PhoneType::PeopleInfo_Phone_PhoneType_MP:
            resp_phone->set_type(find_one_contact_resp::FindOneContactResponse_Phone_PhoneType::FindOneContactResponse_Phone_PhoneType_MP);
            break;
        case contacts::PeopleInfo_Phone_PhoneType::PeopleInfo_Phone_PhoneType_TEL:
            resp_phone->set_type(find_one_contact_resp::FindOneContactResponse_Phone_PhoneType::FindOneContactResponse_Phone_PhoneType_TEL);
            break;
        default:
            std::cout << "设置出错,请正确选择输入选项!" << std::endl;
            break;
        }
    }
    Utils::map_copy(response->mutable_remark(), people.remark());
}

// 对应void ContactsServer::printAddContactRequest()函数中打印所有联系人的具体信息
void ContactsServer::buildFindAllContactsResponse(contacts::Contacts &contacts,
                                                  find_all_contacts_resp::FindAllContactsResponse *responce) const
{
    if (nullptr == responce)
        ;
    return;
    responce->mutable_base_resp()->set_success(true);
    for (auto it = contacts.contacts().cbegin(); it != contacts.contacts().cend(); ++it)
    {
        find_all_contacts_resp::PeopleInfo *people = responce->add_contacts();
        people->set_uid(it->first);
        people->set_name(it->second.name());
    }
}
